	import java.io.IOException;
    import java.util.*;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
    import java.io.InterruptedIOException;
import java.io.ObjectInput;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
import java.net.SocketException;
     
     
    public class Identifier extends ConnectionReader {
            DBlist servers;
            DataList lista;
            static HashMap<Integer,Integer> obciazenie = new HashMap<Integer,Integer>(); //lista obciazen serwerow
            Socket s;
            boolean finish = false;
            private ObjectOutputStream outStream;
            int port ;
           
            public Identifier(Socket s, DBlist servers, DataList lista) {
                    super(new Connection(s));

                    this.servers = servers;
                    this.s = s;
                    this.lista = lista;
                    try {
                            s.setSoTimeout(3000); // czeka 3 sekundy na wiadomosc
                    } catch (Exception e) {}
            }
            
            
           
            @Override
            public void run() {
                                    System.out.println("Oczekuje na indentyfikacje");
                                    Message m = getMessage();
                                    if(m == null) {
                                            System.out.println("Timeout");
                                            return;
                                    }
                   
                                    String command = m.getCommand();
                                    port = m.getSender() ;
                                    if(command.equals("REGISTER")) {
                                            System.out.println("Serwer danych:  "+m.getCommand() + " OK");
                                            servers.addServer(m.getSender(),s);
                                            servers.setObciazenie(m.getSender(), m.getObciazenie());
            						///REJESTRACJA SERWERA                 
                                            Message registerMsg = new Message();
                                            registerMsg.setCommand("kurwa ZAREJESTROWANO NA LB");
                                            servers.sendMessage(m.getSender(), registerMsg);
                                            try {
                                                    s.setSoTimeout(0) ;
                                            } catch (SocketException e) {
                                                    // TODO Auto-generated catch block
                                                    e.printStackTrace();
                                            }
                                            while(true)
                                            {
                                            	
                                            	m = getMessage() ;
                                               	if(m == null)
                                               	{
                                               		System.out.println("Zamykam watek czytelnika") ;
                                               		servers.eraseServer(port) ;//wylaczam serwer
                                               		break ;
                                               	}
                                                if(m.getType() == 8)
                                                {
                                                
                                                    System.out.println("Otrzymalem prosbe o sprawdzenie") ;
                                                    Message m2 = new Message() ;
                                                    

                                                    int i = lista.checkFile(m.getKey(), m.getCommand());
                                                    if (i == -1){
                                                        m2.setPorty(lista.getLista(m.getKey()));
                                                        m2.setCommand(new String("2")); //  2   zmodyfikuj dane
                                                        System.out.println("Trzeba zmodyfikowac dane");
                                                    }
                                                    else if (i == 1) {
                                                         m2.setCommand(new String("3")); //   3   usun dane
                                                         System.out.println("Trzeba usunac dane");
                                                    }

                                                    else {
                                                        m2.setCommand(new String("1")); //    1   ok
                                                        System.out.println("Wszystko ok");
                                                    }
                                                    m2.setKey(m.getKey()) ; //plik jest ok
                                                    m2.setType(8) ;
                                                    servers.sendMessage(m.getSender(), m2) ;

                                                }
                                                    ;

                                                    if(m.getType() == 5 || m.getType() == 6) { //dodawanie lub modyfikacja
                                                        System.out.println("suma kontrolna: " + m.getCommand() + " klucz: " + m.getKey() + " obciazenie: " + m.getObciazenie() + " port " + m.getSender()) ;
 
                                                        lista.addRecord(m.getKey(), m.getCommand(), m.getSender());
                                                        servers.setObciazenie(m.getSender(), m.getObciazenie());
                                                    }
                                                    if(m.getType() == 7) { // usuwanie ??

                                                        lista.deleteRecord(m.getKey());
                                                    }

                                            }
                                    }
            						///OBSLUGA KLIENTA
                                    if(command.equals("GET")) {
                                            System.out.println("Klient: "+m.getCommand() + " OK" + m.getType());

                                            answerClient(m.getKey(), m.getType());
                                            System.out.println("Rozlaczam klienta");
                                            try {
                                                    s.close();
                                            } catch (IOException e) { e.getMessage(); }
                                    }
                                   
                                    
                                    System.out.println("Koniec");  
            }
           
            public void answerClient(int key, int type) {


                    System.out.println("klucz " + key + " typ " + type);
                    LinkedList<Integer> lista_serwerow = new LinkedList<Integer>();
                    Message m = new Message();

                   if (lista.getLista(key) != null && type != 2) {   //jesli istnieje taki klucz i nie jest to INSERT
                        
                        lista_serwerow = lista.getLista(key);
                        
                        System.out.println("Wypisuje liste serwerow dla klucza "+key+ " : ");
                        for(int i=0; i < lista_serwerow.size(); i++) {
                           System.out.println(lista_serwerow.get(i));
                        }
                        m.setPorty(lista_serwerow);
                    }

                    else if (lista.getLista(key) == null  && type == 2)  {         //jesli nie istnieje
                        System.out.println("Zajebiscie, klucz nie istnieje, mozna dodac");
            
                        //wskaz najmniej obciazony serwer

                        lista_serwerow = servers.lista();
                        if(lista_serwerow.size() >= 3)
                        System.out.println("1 " + lista_serwerow.get(0) + " 2 " + lista_serwerow.get(1) + " 3 " + lista_serwerow.get(2));
                       // lista_serwerow.add(2000);
                        m.setPorty(lista_serwerow);
                        
                        
                        
                    }

                    else if (lista.getLista(key) != null && type == 2) {
                        System.out.println("Nie mozna dodac bo taki klucz juz istnieje");
                        m.setType(10); // error, nie mozna dodac bo klucz juz istnieje
                    }

                    else if (lista.getLista(key) == null && type !=2 ) { //chcemy zrobic operacje na kluczu ktory nie istnieje
                        System.out.println("Nie mozna robic operacji na pliku ktory nie istnieje");
                        m.setType(11);
                    }

                    //znajdz na liscie serwerow gdzie przechowywany jest klucz i zwroc tab[2] || numery serw/porty
                    System.out.println("Sending to client");
                    
                    sendMessage(m);
            }
           
            public void sendMessage(Message m) {   
                    try {
                            outStream = new ObjectOutputStream(s.getOutputStream());
                    } catch(Exception e) { System.out.println(e.getMessage()); }
                   
                            System.out.println("Sending message to " + s.getPort());
                            try {
                                    outStream.writeObject(m);
                            } catch (IOException e) {
                                    e.printStackTrace();
                            }
            }
    }

